home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-04-03 | 20.4 KB | 663 lines | [TEXT/MPS ] |
- //----------------------------------------------------------------------------------------
- // UPopup.cp
- // Copyright © 1988-96 by Apple Computer, Inc. All rights reserved.
- //----------------------------------------------------------------------------------------
-
- #ifndef __UPOPUP__
- #include "UPopup.h"
- #endif
-
- // MacApp
-
- #ifndef __UFAILURE__
- #include "UFailure.h"
- #endif
-
- #ifndef __UGEOMETRY__
- #include "UGeometry.h"
- #endif
-
- #ifndef __UMACAPPGLOBALS__
- #include "UMacAppGlobals.h"
- #endif
-
- #ifndef __UMACAPPUTILITIES__
- #include "UMacAppUtilities.h"
- #endif
-
- #ifndef __UMENUMGR__
- #include "UMenuMgr.h"
- #endif
-
- #ifndef __USTREAM__
- #include "UStream.h"
- #endif
-
- #ifndef __UWINDOW__
- #include "UWindow.h"
- #endif
-
- // Toolbox
-
- #ifndef __CONTROLS__
- #include <Controls.h>
- #endif
-
- #ifndef __ERRORS__
- #include <Errors.h>
- #endif
-
- #ifndef __RESOURCES__
- #include <Resources.h>
- #endif
-
- #ifndef __TOOLUTILS__
- #include <ToolUtils.h>
- #endif
-
- // ANSI
-
- #ifndef __STDIO__
- #include <stdio.h>
- #endif
-
- //----------------------------------------------------------------------------------------
- const short kMAPopupRsrcID = 128; // The rsrc id of the Popup CDEF supplied
- // with MacApp.
-
- //----------------------------------------------------------------------------------------
-
- // The following data structure is a private data structure used by the popup CDEF. It
- // lives as a privHdl off the control handle's contrlData field. The first two fields of
- // the private data structure are "public" but the rest are private.
- typedef struct
- {
- MenuRef mHandle; // the popup's menu handle
- short mID; // the popup's menu id
- short mLastMenuID; // last menu id selected (System 7 only)
- short mLastItem; // last item selected (System 7 only)
- SignedByte* mPrivate;
- } popupPrivateData, *popupPrivateDataPtr, **popupPrivateDataHandle;
-
-
- //========================================================================================
- // CLASS TPopup
- //========================================================================================
- #undef Inherited
- #define Inherited TCtlMgr
-
- #pragma segment DlgOpen
- MA_DEFINE_CLASS_M1(TPopup, Inherited);
-
- //----------------------------------------------------------------------------------------
- // TPopup constructor
- //----------------------------------------------------------------------------------------
- #pragma segment DlgOpen
-
- TPopup::TPopup()
- {
- fEventNumber = mPopupHit;
-
- fItemOffset = 0;
- fTitleStyle = popupTitleNoStyle;
- fTitleJust = popupTitleLeftJust;
- fUseAddResMenu = FALSE;
- fUseAddResMenuResType = kNoIdentifier;
- fUseAddResMenuNumberInitialItems = 0;
- fStrListID = kNoResource; // popup's title: STR# rsrc id
- fIndex = kNoResource; // index into STR#
- fMacAppSetDimState = FALSE;
-
- } // TPopup::TPopup
-
- //----------------------------------------------------------------------------------------
- // TPopup::Free:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgClose
-
- TPopup::~TPopup()
- {
- if (fUseAddResMenu) {
- MenuRef theMenuRef = this->GetMenuRef();
-
- if (theMenuRef != NULL) {
- for (short i = CountMItems(theMenuRef); i > fUseAddResMenuNumberInitialItems; i--)
- DeleteMenuItem(theMenuRef, i);
- }
- }
- }
-
- //----------------------------------------------------------------------------------------
- // TPopup::IPopup:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgOpen
-
- void TPopup::IPopup(TView* itsSuperView,
- const VPoint& itsLocation,
- const VPoint& itsSize,
- SizeDeterminer itsHSizeDet,
- SizeDeterminer itsVSizeDet,
- short itsMenuID, // rsrc ID of 'MENU' or 'CMNU' rsrc
- short itsCurrentItem,
- short itsItemOffset, // width of the popup title area
- short itsStrListID, // popup's title: STR# rsrc id
- short itsIndex, // index into STR#
- /* Style */ short itsStyle, // title's style
- short itsJust, // title's justification
- Boolean useAddResMenu, // true if want to AppendResMenu (can use
- // this option iff menuID != kNoResource)
- ResType useAddResMenuResType,// used if useAddResMenu is true
- const TextStyle& itsTextStyle)
-
- {
- fUseAddResMenu = useAddResMenu;
- fUseAddResMenuResType = useAddResMenuResType;
-
- // initialize the popup
- CStr255 itsLabel;
- if (itsStrListID != kNoResource)
- GetIndString(itsLabel, itsStrListID, itsIndex);
- fTitleStyle = itsStyle;
- fTitleJust = itsJust;
- fSizeDeterminer[hSel] = itsHSizeDet; // needed for call to this->GetProcID()
-
- // set up the rest of the instance variables
- fMenuID = itsMenuID;
- fItemOffset = itsItemOffset;
-
- ICtlMgr(itsSuperView, itsLocation, itsSize, itsHSizeDet, itsVSizeDet, itsLabel, itsCurrentItem,
- 0, 0, 0, itsTextStyle);
- } // TPopup::IPopup
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetPopupTitleStyle:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgOpen
-
- unsigned short TPopup::GetPopupTitleStyle()
- {
- unsigned short popupTitleStyle;
-
- // set up justification value
- if (fTitleJust == teJustCenter)
- popupTitleStyle = popupTitleCenterJust;
- else if (fTitleJust == teJustRight)
- popupTitleStyle = popupTitleRightJust;
- else
- popupTitleStyle = popupTitleLeftJust; // default value: note sets high-bit of lo-word
-
- // set up style value
- if (fTitleStyle == normal)
- popupTitleStyle += popupTitleNoStyle;
- else
- {
- if (macroIn(fTitleStyle, bold))
- popupTitleStyle += popupTitleBold;
- if (macroIn(fTitleStyle, italic))
- popupTitleStyle += popupTitleItalic;
- if (macroIn(fTitleStyle, underline))
- popupTitleStyle += popupTitleUnderline;
- if (macroIn(fTitleStyle, outline))
- popupTitleStyle += popupTitleOutline;
- if (macroIn(fTitleStyle, shadow))
- popupTitleStyle += popupTitleShadow;
- if (macroIn(fTitleStyle, condense))
- popupTitleStyle += popupTitleCondense;
- if (macroIn(fTitleStyle, extend))
- popupTitleStyle += popupTitleExtend;
- }
-
- return popupTitleStyle;
- } // TPopup::GetPopupTitleStyle
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetProcID:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgOpen
-
- short TPopup::GetProcID()
- {
- short itsProcID = popupMenuProc;
-
- itsProcID += popupUseWFont; // always use window font
-
- if (fUseAddResMenu)
- itsProcID += popupUseAddResMenu; // set if popup uses AppendResMenu
-
- if (fSizeDeterminer[hSel] == sizeFixed)
- itsProcID += popupFixedWidth; // set if popup has fixed width
-
- return itsProcID;
- } // TPopup::GetProcID
-
- //----------------------------------------------------------------------------------------
- // TPopup::CreateCMgrControl:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgOpen
-
- void TPopup::CreateCMgrControl(const CStr255& itsTitle,
- long itsVal,
- long /* itsMin */,
- long /* itsMax */,
- short /* itsProcID */)// override
- {
- short numInitialItemsInMenu = 0; // used if we are using AppendResMenu
-
- // NOTE: we ignore the values passed in for itsMin, itsMax, and itsProcID since the
- // popup CDEF defines these values differently for the NewControl call. So compute instead...
-
- // look 'n see if it's in the menubar
- MenuRef itsMenu = ::GetMenuHandle(this->GetMenuID());
- if (itsMenu == NULL)
- { // nope, it's not in the menubar...insert it
- itsMenu = this->GetMenuRef();
- if (itsMenu)
- InsertMenu(itsMenu, hierMenu); // stick it in
- else
- {
- #if qDebug
- fprintf(stderr, "TPopup::CreateCMgrControl needs menu id for a MENU or CMNU.\n");
- Failure(resNotFound, 0);
- #endif
- }
- }
-
- if (fUseAddResMenu)
- numInitialItemsInMenu = this->GetNumberOfItems();
-
- TWindow* itsTWindow = this->GetWindow();
- WindowRef itsWindow = itsTWindow ? itsTWindow->fWMgrWindow : gWorkPort;
-
- // set the port appropriately
- GrafPtr savePort;
- GetPort(&savePort);
- SetPortWindowPort(itsWindow);
-
- // Set up the port's text style -- NewControl needs this.
- TextStyle aTextStyle = fTextStyle;
- SetPortTextStyle(aTextStyle);
- PenNormal();
-
- // create the control
- ControlRef aCMgrControl = NewControl(itsWindow, &this->ControlQDArea(), itsTitle, FALSE,
- (short)this->GetPopupTitleStyle(), fMenuID, fItemOffset,
- this->GetProcID(), fUseAddResMenuResType);
- SetPort(savePort); // restore port before signalling failure
- FailNIL(aCMgrControl);
-
- // Need to signal failure if the CDEF's private storage couldn't be created -- this is
- // most likely due to a missing MENU or CMNU resource with fMenuID.
- FailNIL((*aCMgrControl)->contrlData);
-
- SetControlReference(aCMgrControl, (long)this); // Set refCon here, it has a special value at
- // NewControl time - the ResType for the case
- // in which the popup's variation code has
- // popupUseAddResMenu.
-
- fCMgrControl = aCMgrControl;
- this->DimState(fDimmed, kDontRedraw);
-
- // Remember, the control was created with "magic" values, fix it up.
- this->SetLongValues(itsVal, 1, this->GetNumberOfItems(), kDontRedraw);
-
- this->SetCMgrVisibility(itsWindow != gWorkPort);
-
- if (fUseAddResMenu)
- fUseAddResMenuNumberInitialItems = numInitialItemsInMenu;
- } // TPopup::CreateCMgrControl
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetStandardSignature:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgWriteResource
-
- IDType TPopup::GetStandardSignature() // override
- {
- return kStdPopup;
- } // TPopup::GetStandardSignature
-
- //----------------------------------------------------------------------------------------
- // TPopup::ReadFields:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgReadResource
-
- void TPopup::ReadFields(TStream* aStream) // override
- {
- Inherited::ReadFields(aStream);
-
- FailInfo fi;
- Try(fi)
- {
- fMenuID = aStream->ReadInteger();
- short itsCurrentItem = aStream->ReadInteger();
- fItemOffset = aStream->ReadInteger();
-
- fTitleStyle = (Style)aStream->ReadByte();
- fTitleJust = aStream->ReadInteger();
- fUseAddResMenu = aStream->ReadBoolean();
- fUseAddResMenuResType = aStream->ReadLong();
- fStrListID = aStream->ReadInteger();
- fIndex = aStream->ReadInteger();
-
- CStr255 itsLabel;
- this->GetMenuLabel(itsLabel);
-
- // initialize the popup
- this->CreateCMgrControl(itsLabel, itsCurrentItem, 0, 0, 0);
- fi.Success();
- }
- else
- {
- this->Free();
- fi.ReSignal();
- }
- } // TPopup::ReadFields
-
- //----------------------------------------------------------------------------------------
- // TPopup::WriteFields:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgWriteResource
-
- void TPopup::WriteFields(TStream* aStream) // override
- {
- Inherited::WriteFields(aStream);
-
- aStream->WriteInteger(this->GetMenuID());
- aStream->WriteInteger(this->GetCurrentItem());
- aStream->WriteInteger(fItemOffset);
-
- aStream->WriteByte(fTitleStyle);
- aStream->WriteInteger(fTitleJust);
- aStream->WriteBoolean(fUseAddResMenu);
- aStream->WriteLong(fUseAddResMenuResType);
- aStream->WriteInteger(fStrListID);
- aStream->WriteInteger(fIndex);
- } // TPopup::WriteFields
-
- //----------------------------------------------------------------------------------------
- // TView::Focus:
- //----------------------------------------------------------------------------------------
- #pragma segment MAViewRes
-
- Boolean TPopup::Focus()
- {
- // To Focus, must be able to focus, and be drawable, so as to avoid a bug in the
- // CDEF/MDEF in which a bus error results when drawing if the popup isn't
- // drawable (e.g. if it's off-screen).
- return Inherited::Focus() && !((CRect&)(*GetClipRegion(qd.thePort))->rgnBBox).Empty();
- } // TView::Focus
-
- //----------------------------------------------------------------------------------------
- // TPopup::Draw:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::Draw(const VRect& area) // override
- {
- // may need to set the lo memory globals for the font/size since the CDEF will
- // occasionally ignore the values
-
- if (this->GetNumberOfItems() == 0)
- {
- fMacAppSetDimState = TRUE;
- this->DimState(TRUE, kDontRedraw); //no items, Dim Popup
- }
- else if (fDimmed && fMacAppSetDimState)
- {
- fMacAppSetDimState = FALSE;
- this->DimState(FALSE,kDontRedraw);
- }
-
- Inherited::Draw(area);
- } // TPopup::Draw
-
- //----------------------------------------------------------------------------------------
- // TPopup::DoMouseCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::DoMouseCommand(VPoint& theMouse,
- TToolboxEvent* event,
- CPoint hysteresis)// override
- {
- if (!this->Focus()) // set up the font/size
- {
- TextStyle aTextStyle = fTextStyle;
- SetPortTextStyle(aTextStyle);
- }
-
- Inherited::DoMouseCommand(theMouse, event, hysteresis);
- } // TPopup::DoMouseCommand
-
- //----------------------------------------------------------------------------------------
- // TPopup::AttachMenuRef:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::AttachMenuRef(MenuRef itsMenuRef)
- {
- MenuRef currentMenuRef;
-
- // first, a quick safety check to make sure that we do nothing if we are trying to
- // install a menu that is already installed
- currentMenuRef = this->GetMenuRef();
- if (currentMenuRef != itsMenuRef)
- {
- if (currentMenuRef) // first, release the old MenuRef
- {
- // There are 3 cases that we need to account for here:
- // 1. if fMenuRef is a converted 'CMNU' resource => leave MenuRef alone;
- // 2. if fMenuRef is a 'MENU' resource => call ReleaseResource;
- // 3. if fMenuRef is a menu created with NewMenu => call DisposeMenu.
- // N.B.: you should never call GetMenu to create the MenuRef, instead call MAGetMenu.
- if (IsManagedMenu(currentMenuRef))// case 1
- ; // do nothing
- else if (IsAResource((Handle)currentMenuRef))// case 2
- ReleaseResource((Handle)currentMenuRef);
- else // case 3
- DisposeMenu(currentMenuRef);
- currentMenuRef = NULL;
- this->SetCMgrVisibility(FALSE);
- SizeControl(fCMgrControl, 0, 0);
- DisposeControl(fCMgrControl);
- fCMgrControl = NULL;
- }
-
- // set the menu handle in the popup's private storage
- if (itsMenuRef)
- {
- fMenuID = (*itsMenuRef)->menuID;
- CStr255 itsTitle;
- this->GetMenuLabel (itsTitle);
- this->CreateCMgrControl(itsTitle, 1 , 0, 0, 0);
-
- // set up the control's needed values
- this->SetLongValues(1, 1, this->GetNumberOfItems(), kDontRedraw);
- }
- }
- } // TPopup::AttachMenuRef
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetMenuRef:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- MenuRef TPopup::GetMenuRef()
- {
- return MAGetMenu(this->GetMenuID());
- } // TPopup::GetMenuRef
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetMenuLabel:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::GetMenuLabel(CStr255& itsLabel)
- {
- if (fStrListID != kNoResource) // retrieve the menu label from the resource
- GetIndString(itsLabel, fStrListID, fIndex);
- else
- {
- MenuRef itsMenuRef; // retrieve the menu label from the menu
- if ((itsMenuRef = this->GetMenuRef()) != NULL)
- GetMenuItemText(itsMenuRef, 0, itsLabel);
- else
- itsLabel.Empty();
- }
- } // TPopup::GetMenuLabel
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetCurrentCommand:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- CommandNumber TPopup::GetCurrentCommand()
- {
- return CommandFromMenuItem(this->GetLastMenuID(), this->GetLastItem());
- } // TPopup::GetCurrentCommand
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetCurrentItem:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- short TPopup::GetCurrentItem()
- {
- return this->GetVal();
- } // TPopup::GetCurrentItem
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetLastItem:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- short TPopup::GetLastItem()
- {
- #if 0
- // the following code is only supported for the System 7 CDEF
- if (fCMgrControl)
- {
- short lastItem = GetControlMaximum(fCMgrControl);
-
- //SRF if ((lastItem = (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mLastItem) != 0)
- if (lastItem)
- return lastItem;
- }
-
- #endif
- return this->GetCurrentItem();
- } // TPopup::GetLastItem
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetMenuID:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- short TPopup::GetMenuID()
- {
- return fMenuID;
- } // TPopup::GetMenuID
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetLastMenuID:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- short TPopup::GetLastMenuID()
- {
- #if 0
- // the following code is only supported for the System 7 CDEF
- if (fCMgrControl)
- {
- short lastMenuID = (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mLastMenuID);
-
- //SRF if ((lastMenuID = (*(popupPrivateDataHandle)(*fCMgrControl)->contrlData)->mLastMenuID) != 0)
- if (lastMenuID)
- return lastMenuID;
- }
-
- #endif
- return this->GetMenuID(); // default if no last result
- } // TPopup::GetLastMenuID
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetItemText:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::GetItemText(short item,
- CStr255& theText)
- {
- MenuRef itsMenuRef;
-
- if ((itsMenuRef = this->GetMenuRef()) != NULL)
- GetMenuItemText(itsMenuRef, item, theText);
- else
- theText.Empty();
- } // TPopup::GetItemText
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetNumberOfItems:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- short TPopup::GetNumberOfItems()
- {
- MenuRef itsMenuRef;
- if ((itsMenuRef = this->GetMenuRef()) != NULL)
- return CountMItems(itsMenuRef); // if possible, query the menu
- else
- return this->GetMax(); // else query the control
- } // TPopup::GetNumberOfItems
-
- //----------------------------------------------------------------------------------------
- // TPopup::GetTitle:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::GetTitle(CStr255& title)
- {
- this->GetText(title);
- } // TPopup::GetTitle
-
- //----------------------------------------------------------------------------------------
- // TPopup::SetCurrentItem:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::SetCurrentItem(short item,
- Boolean redraw)
- {
- this->SetLongVal(item, redraw);
- } // TPopup::SetCurrentItem
-
- //----------------------------------------------------------------------------------------
- // TPopup::SetPopup:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::SetPopup(MenuRef itsMenuRef,
- short itsCurrentItem,
- Boolean redraw)
- {
- this->AttachMenuRef(itsMenuRef);
- this->SetCurrentItem(itsCurrentItem, redraw);
- if (redraw)
- this->ForceRedraw();
- } // TPopup::SetPopup
-
- //----------------------------------------------------------------------------------------
- // TPopup::SetTitle:
- //----------------------------------------------------------------------------------------
- #pragma segment DlgRes
-
- void TPopup::SetTitle(const CStr255& title)
- {
- this->SetText(title, kDontRedraw);
- } // TPopup::SetTitle
-
- //----------------------------------------------------------------------------------------
- // End of UPopup.cp
-
- #pragma segment Inline
-